package com.code.generator.cn.util.fb;


import com.code.generator.cn.entity.CoderField;
import com.code.generator.cn.entity.CoderTable;
import com.code.generator.cn.util.MyFileUtil;
import com.code.generator.cn.util.PathUtil;
import com.code.generator.cn.util.base.CommonUtil;
import com.code.generator.cn.util.base.MapperUtil;
import com.code.generator.cn.util.base.MyStringChangeUtil;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;

import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class FbMapperUtil extends MapperUtil {

    public static void createMapper(CoderTable coderTable, List<CoderField> coderFields, Configuration configuration, String projPath) throws IOException, TemplateException {

        Writer file = null;

        String className = coderTable.getModifyName();
        Template temp = configuration.getTemplate("/fb/mapper.ftl");


        //获取包名
        String packageName  = PathUtil.getCreateBasePath(coderTable);


        String groupPath = packageName.replace(".", "/");
        //生成entity的路径
        String mapperPath = projPath + "/src/main/java/" + groupPath + "/mapper/";
        //设置生成的路径
        MyFileUtil.createFileDir(mapperPath);
        //设置生成的属性
        Map<String, Object> createMap = new HashMap<>();
        CommonUtil.createFbBaseInfo(coderTable, createMap);
        CommonUtil.createPrimary(coderFields, createMap);
        //设置生成的文件名
        file = new FileWriter(mapperPath + className + "Mapper.java");
        temp.process(createMap, file);
        file.close();

    }

    private static void createInfo(Map<String, Object> createMap,CoderTable coderTable, List<CoderField> coderFields) {
        //设置实体对象要生成的包名
        createMap.put("packageName", coderTable.getPackageName());
        //设置对象名称
        createMap.put("className", coderTable.getModifyName());
        //设置表名
        createMap.put("tableName", coderTable.getTableName());
        //设置响应对象的名称classPageName
        createMap.put("classPageName", coderTable.getModifyName() + "Vo");
        //设置请求对象的名称classSearchName
        createMap.put("classSearchName", coderTable.getModifyName() + "QueryDto");
        //设置对象字段
        List<Map<String, Object>> fieldList = new ArrayList<>();
        //设置请求参数的列表
        List<Map<String, Object>> paramList = new ArrayList<>();
        //设置要显示的参数列表集合
        List<Map<String, Object>> fieldPageList = new ArrayList<>();

        StringBuilder columnStr = new StringBuilder();

        for (CoderField coderField : coderFields) {
            //组装主键信息
            createPrimaryInfo(createMap, coderField);
            //组装数据基本字段
            createBaseFieldList(createMap, fieldList, coderField);
            //组装查询信息，如果字段包含了查询条件
            createSearchList(createMap, paramList, coderField);
            //组装基本字段
            createColumn(createMap, columnStr, coderField);
            createPageList(fieldPageList, coderField);
        }
        createMap.put("fieldPageList", fieldPageList);
    }

    private static void createPageList(List<Map<String, Object>> fieldPageList, CoderField coderField) {
        if (coderField.getIsTable() == 1) {
            Map<String, Object> fieldPage = new HashMap<>();
            fieldPage.put("fieldName", coderField.getFieldName());
            fieldPage.put("fieldType", MyStringChangeUtil.changeFiledType(coderField.getFieldType()));
            fieldPage.put("classFieldName", coderField.getClassFieldName());
            fieldPage.put("isPramary", coderField.getIsPrimary());
            fieldPageList.add(fieldPage);
        }
    }

    private static void createColumn(Map<String, Object> createMap, StringBuilder columnStr, CoderField coderField) {
        columnStr.append("a." + coderField.getFieldName() + ",");
        String column = columnStr.toString().substring(0, columnStr.length() - 1);
        createMap.put("column", column);
    }

    private static void createSearchList(Map<String, Object> createMap, List<Map<String, Object>> paramList, CoderField coderField) {
        if (coderField.getIsSearch() == 1) {
            if (coderField.getSearchWay() != 7 && coderField.getSearchWay() != 9) {
                Map<String, Object> paramMap = new HashMap<>();
                paramMap.put("classFieldName", coderField.getClassFieldName());
                String sql = getSearchSql(coderField);
                paramMap.put("whereSql", sql);
                paramList.add(paramMap);
            } else {
                String upClassFileName=MyStringChangeUtil.changeField(coderField.getFieldName(),3);
                if(coderField.getSearchWay()==7) {
                    Map<String, Object> startMap = new HashMap<>();
                    startMap.put("classFieldName", "start"+upClassFileName);
                    String startSql= "<![CDATA[and a."+coderField.getFieldName()+" >= #{start"+upClassFileName+"}]]>";
                    startMap.put("whereSql",startSql);
                    paramList.add(startMap);

                    Map<String, Object> endMap = new HashMap<>();
                    endMap.put("classFieldName", "end"+upClassFileName);
                    String endSql= "<![CDATA[and a."+coderField.getFieldName()+" <= #{end"+upClassFileName+"}]]>";
                    endMap.put("whereSql",endSql);
                    paramList.add(endMap);
                }
                if(coderField.getSearchWay()==8) {
                    Map<String, Object> startMap = new HashMap<>();
                    startMap.put("classFieldName", "start"+upClassFileName);
                    String startSql= "<![CDATA[and a."+coderField.getFieldName()+" > #{start"+upClassFileName+"}]]>";
                    startMap.put("whereSql",startSql);
                    paramList.add(startMap);

                    Map<String, Object> endMap = new HashMap<>();
                    endMap.put("classFieldName", "end"+upClassFileName);
                    String endSql= "<![CDATA[and a,"+coderField.getFieldName()+" < #{end"+upClassFileName+"}]]>";
                    endMap.put("whereSql",endSql);
                    paramList.add(endMap);
                }
            }
        }
        createMap.put("paramList", paramList);
    }

    /**
     * //查询方式 1.等于 2.模糊匹配 3.小于 4大于 5小于等于 6大于等于 7.包含闭区间  8包含开区间
     *
     * @param coderField
     */
    private static String getSearchSql(CoderField coderField) {
        if (coderField.getSearchWay() == 1) {
            return "and a." + coderField.getFieldName() + "=#{" + coderField.getClassFieldName() + "} ";
        } else if (coderField.getSearchWay() == 2) {
            return "and a." + coderField.getFieldName() + " like CONCAT('%',#{" + coderField.getClassFieldName() + "},'%')";
        } else if (coderField.getSearchWay() == 3) {
            return "<![CDATA[and a." + coderField.getFieldName() + " < #{" + coderField.getClassFieldName() + "}]]>";
        } else if (coderField.getSearchWay() == 4) {
            return "<![CDATA[and a." + coderField.getFieldName() + " > #{" + coderField.getClassFieldName() + "}]]>";
        } else if (coderField.getSearchWay() == 5) {
            return "<![CDATA[and a." + coderField.getFieldName() + " <= #{" + coderField.getClassFieldName() + "}]]>";
        } else if (coderField.getSearchWay() == 6) {
            return "<![CDATA[and a." + coderField.getFieldName() + " >= #{" + coderField.getClassFieldName() + "}]]>";
        } else if (coderField.getSearchWay() == 7) {
            return "<![CDATA[and a." + coderField.getFieldName() + " >= #{start_" + coderField.getClassFieldName() + "} and a." + coderField.getFieldName() + " <=  #{end_" + coderField.getClassFieldName() + "}]]> ";
        } else if (coderField.getSearchWay() == 8) {
            return "<![CDATA[and a." + coderField.getFieldName() + " > #{start_" + coderField.getClassFieldName() + "} and a." + coderField.getFieldName() + " <  #{end_" + coderField.getClassFieldName() + "}]]> ";
        }
        return "";
    }


    /**
     * 组装主键信息
     *
     * @param createMap
     * @param coderField
     */
    private static void createPrimaryInfo(Map<String, Object> createMap, CoderField coderField) {
        if (coderField.getIsPrimary() == 1) {
            createMap.put("primary", coderField.getFieldName());
            createMap.put("primaryType", MyStringChangeUtil.changeFiledType(coderField.getFieldType()));
            createMap.put("primaryClassName", coderField.getClassFieldName());
        }
    }


    /**
     * 组装基本数据
     *
     * @param fieldList
     * @param coderField
     */
    private static void createBaseFieldList(Map<String, Object> createMap, List<Map<String, Object>> fieldList, CoderField coderField) {
        Map<String, Object> fieldMap = new HashMap<>();
        fieldMap.put("fieldName", coderField.getFieldName());
        fieldMap.put("fieldType", MyStringChangeUtil.changeFiledType(coderField.getFieldType()));
        fieldMap.put("classFieldName", coderField.getClassFieldName());
        fieldMap.put("isPramary", coderField.getIsPrimary());
        fieldList.add(fieldMap);
        createMap.put("fieldList", fieldList);

    }

    public static void createMapperXml(CoderTable coderTable, List<CoderField> coderFields, Configuration configuration, String projPath) throws IOException, TemplateException {

        Writer file = null;

        String className = coderTable.getModifyName();
        Template temp = configuration.getTemplate("/fb/mapperXml.ftl");


        //获取包名
        String packageName  = PathUtil.getCreateBasePath(coderTable);

        String groupPath = packageName.replace(".", "/");
        //生成entity的路径
        String mapperPath = projPath + "/src/main/java/" + groupPath + "/mapper/";
        //设置生成的路径
        MyFileUtil.createFileDir(mapperPath);
        //设置生成的属性
        Map<String, Object> createMap = new HashMap<>();
        createInfo(createMap, coderTable, coderFields);
        CommonUtil.createFbBaseInfo(coderTable, createMap);
        //设置生成的文件名
        file = new FileWriter(mapperPath + className + "Mapper.xml");
        temp.process(createMap, file);
        file.close();
    }
}
